﻿using System;
using Results.Models;

namespace Results.ViewModels
{
    /// <summary>
    /// Main data context for all views
    /// </summary>
    public class MainViewModel : ViewModelBase, INotifySelection
    {
        /// <summary>
        /// What to show on the screen
        /// </summary>
        public enum ShowOptions { Players, Player, Tournaments, Tournament, Rankings };

        /// <summary>
        /// All other view models
        /// </summary>
        public RankingsViewModel RankingsViewModel { get; private set; }
        public PlayersViewModel PlayersViewModel { get; private set; }
        public TournamentsViewModel TournamentsViewModel { get; private set; }
        public GroupsViewModel GroupsViewModel { get; private set; }
        public SeasonsViewModel SeasonsViewModel { get; private set; }

        /// <summary>
        /// Commands to invoke when "tabs" are selected
        /// </summary>
        public RelayCommand ShowTournament { get; private set; }
        public RelayCommand ShowTournaments { get; private set; }
        public RelayCommand ShowPlayer { get; private set; }
        public RelayCommand ShowPlayers { get; private set; }
        public RelayCommand ShowRankings { get; private set; }

        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="mainModel">The source data</param>
        public MainViewModel(MainModel mainModel)
        {
            // build the other view models
            RankingsViewModel = new RankingsViewModel(mainModel.ResultsModel);
            PlayersViewModel = new PlayersViewModel(mainModel.PlayersModel);
            TournamentsViewModel = new TournamentsViewModel(mainModel.TournamentsModel);
            SeasonsViewModel = new SeasonsViewModel(mainModel.TournamentsModel, this);
            GroupsViewModel = new GroupsViewModel(mainModel.ResultsModel, this);
            SelectedPlayer = new PlayerViewModel(new PlayerModel(), this);
            SelectedTournament = new TournamentViewModel(new TournamentModel(), this);

            // build the command handlers
            ShowTournament = new RelayCommand(p => Show = ShowOptions.Tournament);
            ShowTournaments = new RelayCommand(p => Show = ShowOptions.Tournaments);
            ShowPlayer = new RelayCommand(p => Show = ShowOptions.Player);
            ShowPlayers = new RelayCommand(p => Show = ShowOptions.Players);
            ShowRankings = new RelayCommand(p => Show = ShowOptions.Rankings);

            // start by showing the players tab
            Show = ShowOptions.Players;

            // start by showing the first season
            if (SeasonsViewModel.Seasons.Count > 0)
            {
                var season = SeasonsViewModel.Seasons[0];
                SelectedSeason = season.Season;
                season.Selected = true;
            }

            // start by showing the first group
            if (GroupsViewModel.Groups.Count > 0)
            {
                var group = GroupsViewModel.Groups[0];
                SelectedGroup = group.Group;
                group.Selected = true;
            }

            Query();
        }

        void Query()
        {
            RankingsViewModel.Query(SelectedGroup, SelectedSeason, this);
            PlayersViewModel.Query(SelectedGroup, SelectedSeason, this);
            TournamentsViewModel.Query(SelectedGroup, SelectedSeason, this);
            SelectedTournament.Query(SelectedGroup, this);
        }

        PlayerViewModel _selectedPlayer;
        public PlayerViewModel SelectedPlayer
        {
            get
            {
                return _selectedPlayer;
            }
            set
            {
                if (_selectedPlayer != value)
                {
                    _selectedPlayer = value;
                    Notify("SelectedPlayer");
                }
            }
        }

        TournamentViewModel _selectedTournament;
        public TournamentViewModel SelectedTournament
        {
            get
            {
                return _selectedTournament;
            }
            set
            {
                if (_selectedTournament != value)
                {
                    _selectedTournament = value;
                    _selectedTournament.Query(SelectedGroup, this);
                    Notify("SelectedTournament");
                }
            }
        }

        String _selectedSeason;
        public String SelectedSeason
        {
            get
            {
                return _selectedSeason;
            }
            set
            {
                if (_selectedSeason != value)
                {
                    _selectedSeason = value;
                    Notify("SelectedSeason");
                }
            }
        }

        String _selectedGroup;
        public String SelectedGroup
        {
            get
            {
                return _selectedGroup;
            }
            set
            {
                if (_selectedGroup != value)
                {
                    _selectedGroup = value;
                    Notify("SelectedGroup");
                }
            }
        }

        ShowOptions _show;
        public ShowOptions Show
        {
            get
            {
                return _show;
            }
            set
            {
                if (_show != value)
                {
                    _show = value;
                    Notify("Show");
                }
            }
        }

        #region INotifySelection Members

        public void PlayerSelected(PlayerModel playerModel)
        {
            SelectedPlayer = new PlayerViewModel(playerModel, this);
            Show = ShowOptions.Player;
        }

        public void TournamentSelected(TournamentModel tournamentModel)
        {
            SelectedTournament = new TournamentViewModel(tournamentModel, this);
            Show = ShowOptions.Tournament;
        }

        public void SeasonSelected(String season)
        {
            SelectedSeason = season;
            Query();
        }

        public void GroupSelected(String group)
        {
            SelectedGroup = group;
            Query();
        }

        #endregion
    }
}
